﻿(function ($) {
    $.fn.tabs = function (options) {
        $.fn.tabs.opts = $.extend({}, $.fn.tabs.defaults, options);
        $.fn.tabs.selector = $(this).selector;
        $.fn.tabs.tabCounter = 0;

        this.each(function () {
            $.fn.tabs.innerTabs = $.fn.tabs.updateHeader();

            var IE_BugFix = 0;
            var tabCounter = 0;
            $(this).children().each(function () {
                $(this).attr('id', $.fn.tabs.opts.contentId + '_' + tabCounter);
                IE_BugFix = $.fn.tabs.createTabHeader(tabCounter, this);
                tabCounter++;
            }).hide();
            $.fn.tabs.tabCounter = tabCounter;
        });
        if ($.fn.tabs.opts.templateToAdd == '') {
            $.fn.tabs.opts.templateToAdd = '#' + $($.fn.tabs.selector).children()[0].id;
            $.fn.tabs.template = $($.fn.tabs.opts.templateToAdd).clone();
        }
        else {
            $.fn.tabs.template = $($.fn.tabs.opts.templateToAdd).clone();
        }

        $.fn.tabs.select(0);

        return this;
    };

    $.fn.tabs.select = function (id) {
        $($.fn.tabs.selector).children().hide();
        $('#' + $.fn.tabs.opts.contentId + '_' + id).show();
        $.fn.tabs.innerTabs.children().removeClass('selected');
        $('#tabHeader_' + id).addClass('selected');
    };

    $.fn.tabs.createTabHeader = function (tabCounter, tabContext) {
        var tabHeader = {};
        tabHeader = $('<li></li>');
        tabHeader.click(function () {
            var id = this.id.split('_')[1];
            $.fn.tabs.select(id);
        });
        tabHeader.attr('id', 'tabHeader_' + tabCounter)
		.css('width', $.fn.tabs.opts.tabWidth + 'px')
		.appendTo($.fn.tabs.innerTabs);

        $.fn.tabs.createTitle('', tabCounter);
        return 0;
    };

    $.fn.tabs.createTitle = function (text, id) {
        var tabTitle = $('<span></span>');
        if (text.length > 0) {
            $($.fn.tabs.opts.tabHeader + '_' + id).attr('title', text);
            if (text.length > (+$.fn.tabs.opts.tabTitleLength)) {
                text = text.substring(0, (+$.fn.tabs.opts.tabTitleLength - 3)) + '...';
            }
            tabTitle.text(text + ' ');
        }
        else if ($.fn.tabs.opts.tabTitleClass.length == 0) {
            if ($.fn.tabs.opts.newTabTitle.length > 0) {
                tabTitle.text($.fn.tabs.opts.newTabTitle);
                $($.fn.tabs.opts.tabHeader + '_' + id).attr('title', $.fn.tabs.opts.newTabTitle);
            }
            else {
                tabTitle.text(id.toString());
                $($.fn.tabs.opts.tabHeader + '_' + id).attr('title', id.toString());
            }
        }
        else {
            var title = $('#' + $.fn.tabs.opts.contentId + '_' + id).find($.fn.tabs.opts.tabTitleClass).text();
            $($.fn.tabs.opts.tabHeader + '_' + id).attr('title', title + ' ');
            if (title.length > (+$.fn.tabs.opts.tabTitleLength)) {
                title = title.substring(0, (+$.fn.tabs.opts.tabTitleLength - 3)) + '...';
            }
            tabTitle.text(title + ' ');
        }

        if ($.fn.tabs.opts.isDeleteBtn) {
            $('<a href="#">X</a>').click(function () {
                var idToDelete = $(this).parent().parent()[0].id;
                idToDelete = idToDelete.split('_')[1];
                $.fn.tabs.deleteTab(idToDelete);
                return false;
            }).attr('title', $.fn.tabs.opts.deleteBtnTitle)
	        .appendTo(tabTitle);
        }

        $($.fn.tabs.opts.tabHeader + '_' + id).empty().append(tabTitle);
    };

    $.fn.tabs.deleteTab = function (id) {
        $('#tabHeader_' + id).remove();
        $('#' + $.fn.tabs.opts.contentId + '_' + id).remove();
        $.fn.tabs.tabCounter--;
        for (var i = (+id); i < $.fn.tabs.tabCounter; i++) {
            $('#tabHeader_' + (i + 1))[0].id = 'tabHeader_' + i;
            $('#' + $.fn.tabs.opts.contentId + '_' + (i + 1))[0].id = $.fn.tabs.opts.contentId + '_' + i;
        }
        $.fn.tabs.select(0);
        if ($.fn.tabs.opts.deleteCallback) $.fn.tabs.opts.deleteCallback(id);
    };

    $.fn.tabs.updateHeader = function () {

        var innerTabs = $('<ul class="innerTabs"></ul>');
        innerTabs.css('width', $.fn.tabs.opts.width + 'px');
        $($.fn.tabs.opts.tabHeader + ' .tabs').children().remove();

        $($.fn.tabs.opts.tabHeader + ' .tabs').css('width', $.fn.tabs.opts.tabHeaderWidth + 'px')
		.css('overflow', 'hidden')
		.css('padding', '0')
		.append(innerTabs);

        if ($.fn.tabs.opts.isSortable) {
            $($.fn.tabs.opts.tabHeader + ' .tabs > .innerTabs').sortable({
                stop: function () {
                    $.fn.tabs.reorderTabs();
                }
            });
        }

        $($.fn.tabs.opts.tabHeader + ' .next').unbind('click').click(function () {
            if ($.fn.tabs.currentContent < $.fn.tabs.tabCounter - 1) {
                $('#tabHeader_' + $.fn.tabs.currentContent).hide($.fn.tabs.opts.speed);
                $.fn.tabs.currentContent++;
            }
        });

        $($.fn.tabs.opts.tabHeader + ' .prev').unbind('click').click(function () {
            if ($.fn.tabs.currentContent > 0) {
                $('#tabHeader_' + ($.fn.tabs.currentContent - 1)).show($.fn.tabs.opts.speed);
                $.fn.tabs.currentContent--;
            }
        });

        $($.fn.tabs.opts.tabHeader + ' .add').unbind('click').click(function () {
            $.fn.tabs.add();
        });
        return innerTabs;
    };

    $.fn.tabs.add = function () {
        var newTabContent = $.fn.tabs.template.clone().each(function () {
            this.id = $.fn.tabs.opts.contentId + '_' + $.fn.tabs.tabCounter;
        });
        newTabContent.find($.fn.tabs.opts.tabTitleClass).text($.fn.tabs.opts.newTabTitle);
        $($.fn.tabs.selector).append(newTabContent);
        $.fn.tabs.createTabHeader($.fn.tabs.tabCounter, newTabContent);
        $.fn.tabs.select(0);
        if ($.fn.tabs.opts.addCallback) $.fn.tabs.opts.addCallback($.fn.tabs.tabCounter);
        $.fn.tabs.tabCounter++;
    };

    $.fn.tabs.reorderTabs = function () {
        var tabCounter = 0;
        var ids = $($.fn.tabs.opts.tabHeader + ' .tabs > .innerTabs').sortable('serialize');
        var contents = $($.fn.tabs.selector).children();
        var isFirst = true;
        var newFirstHeaderId = 0;

        for (var i = 0; i < ids.split('&').length; i++) {
            var segment = ids.split('&')[i];
            if (segment.split('=')[1] != i) {
                var headerIdLen = ids.split('&')[i].split('=')[0].length;
                var headerPerfix = segment.split('=')[0].substring(0, headerIdLen - 2);
                var oldHeaderId = segment.split('=')[1];
                var newHeaderId = i;

                if (isFirst) {
                    if (oldHeaderId > newHeaderId + 1) {
                        $.fn.tabs.swap(oldHeaderId, newHeaderId, headerPerfix);
                        return;
                    }
                    $('#' + headerPerfix + '_' + oldHeaderId)[0].id = headerPerfix + '_-1';
                    $('#' + $.fn.tabs.opts.contentId + '_' + oldHeaderId)[0].id = $.fn.tabs.opts.contentId + '_-1';
                    if ($.fn.tabs.opts.reorderCallback) $.fn.tabs.opts.reorderCallback(oldHeaderId.toString(), '-1');
                    newFirstHeaderId = newHeaderId;
                }
                else {
                    $('#' + headerPerfix + '_' + oldHeaderId)[0].id = headerPerfix + '_' + newHeaderId;
                    $('#' + $.fn.tabs.opts.contentId + '_' + oldHeaderId)[0].id = $.fn.tabs.opts.contentId + '_' + newHeaderId;
                    if ($.fn.tabs.opts.reorderCallback) $.fn.tabs.opts.reorderCallback(oldHeaderId.toString(), newHeaderId.toString());
                }
                isFirst = false;
            }
        }
        if ($('#' + headerPerfix + '_-1')[0] != undefined) {
            $('#' + headerPerfix + '_-1')[0].id = headerPerfix + '_' + newFirstHeaderId;
            $('#' + $.fn.tabs.opts.contentId + '_-1')[0].id = $.fn.tabs.opts.contentId + '_' + newFirstHeaderId;
            if ($.fn.tabs.opts.reorderCallback) $.fn.tabs.opts.reorderCallback('-1', newFirstHeaderId.toString());
        }
    };

    $.fn.tabs.swap = function (oldHeaderId, newHeaderId, headerPerfix) {
        $('#' + headerPerfix + '_' + oldHeaderId)[0].id = headerPerfix + '_-1';
        $('#' + $.fn.tabs.opts.contentId + '_' + oldHeaderId)[0].id = $.fn.tabs.opts.contentId + '_-1';
        if ($.fn.tabs.opts.reorderCallback) $.fn.tabs.opts.reorderCallback(oldHeaderId.toString(), '-1');
        for (var i = +oldHeaderId - 1; i >= +newHeaderId; i--) {
            $('#' + headerPerfix + '_' + i)[0].id = headerPerfix + '_' + (i + 1);
            $('#' + $.fn.tabs.opts.contentId + '_' + i)[0].id = $.fn.tabs.opts.contentId + '_' + (i + 1);
            if ($.fn.tabs.opts.reorderCallback) $.fn.tabs.opts.reorderCallback(i.toString(), (i + 1).toString());
        }
        $('#' + headerPerfix + '_-1')[0].id = headerPerfix + '_' + newHeaderId;
        $('#' + $.fn.tabs.opts.contentId + '_-1')[0].id = $.fn.tabs.opts.contentId + '_' + newHeaderId;
        if ($.fn.tabs.opts.reorderCallback) $.fn.tabs.opts.reorderCallback('-1', newHeaderId.toString());
    };

    $.fn.tabs.currentContent = 0;
    $.fn.tabs.selector = '';
    $.fn.tabs.tabCounter = 0;
    $.fn.tabs.innerTabs = {};
    $.fn.tabs.template = {};

    $.fn.tabs.opts = {};
    $.fn.tabs.defaults = {
        width: 500,
        tabWidth: 100,
        tabHeaderWidth: 330,
        headerHeight: 30,
        tabHeader: '#tabHeader',
        contentId: 'tabContent',
        tabTitleClass: '',
        tabTitleLength: 15,
        newTabTitle: '',
        speed: 'fast',
        templateToAdd: '',
        isDeleteBtn: true,
        isSortable: true,
        deleteBtnTitle: 'Delete',

        reorderCallback: function (oldId, newId) { },
        addCallback: function (lastId) { },
        deleteCallback: function (id) { }
    };
})(jQuery);
